/* 
File: pixmap.h
Class for reading and storing a pixmap in RGB format.
Abstract class that can read a pixmap from a file.
Subclasses to be created which can read a pixmap from a
file in a certain format (e.g., RGB format).
*/

#ifndef PIXMAP_H
#define PIXMAP_H

#include <stdio.h>
#include <stdlib.h>

/*
A pixel has three values (red, green, blue) each ranging
from 0 to 255, represented as unsigned chars.
A pixmap is a matrix of pixels.
This storage format corresponds to that used by OpenGL.
*/

/* Data structure for a single pixel */
struct OnePixel
{
  unsigned char r;
  unsigned char g;
  unsigned char b;
};

/* Data structure for the whole pixmap */
class Pixmap
{
  public:
  
  /* number of pixels in width and height */
  int w, h; 
  
  /* the pixels */
  struct OnePixel * pixels;

  /* allocate pixmap of given width and height, all
     pixels will be black */
  inline void make(int ww, int hh)
  {
    pixels = (OnePixel *) calloc(ww*hh,sizeof(OnePixel));
    if (pixels)  {  w = ww;  h = hh;  }
    else { w = h = 0;  }
  }

  /* free pixmap, if allocated */
  inline void kill(void)
  {  if (pixels) delete pixels; 
     w = h = 0; pixels = NULL;
  }

  /* constructor */
  inline Pixmap() {  w = h = 0; pixels = NULL;  }

  /* destructor */
  inline ~Pixmap() {  kill();  }
  
  /* return the position of pixel (i,j) in the matrix */
  inline int pos(int i, int j) {  return (i+w*j);  }


}; // end class

/*
Abstract class that can read a pixmap from a file.
The implementation of the functions will be given in its
subclasses (a subclass for each file format). 
*/
class PixmapReader
{
  public:

  /* return 1 if the file name has the correct extension
     (thus it is likely that contents are in the correct format),
     0 otherwise */
  virtual int okFilename(char *filename) = 0;

  /* read pixmap from file, return 1 if success, 0 otherwise */  
  virtual int readPixmap(FILE *fd, class Pixmap *map) = 0;

  /* for convenience */
  inline int readPixmap(char *filename, class Pixmap *map)
  {
    FILE * fd;
    if (!okFilename(filename)) return 0;
    fd = fopen(filename,"r");
    if (!fd) return 0;
    return readPixmap(fd, map);
  }

};

#endif
